home *** CD-ROM | disk | FTP | other *** search
- unit main;
-
- {Source Code for Registry Enumerator (copy right) Greg Lorriman 1998.
-
- Compiled with Delphi2.
-
- email :greg@lorriman.demon.co.uk web : http://www.lorriman.demon.co.uk
-
- You will also need the RxLib components and Eric Fookes's super label components.
- }
-
- interface
-
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, Ef_Edit, ComCtrls, ExtCtrls, Nestinfo, Buttons, Menus,registry,
- Placemnt, FileOp;
-
-
-
- type
- TForm1 = class(TForm)
- Panel1: TPanel;
- Panel2: TPanel;
- Panel3: TPanel;
- Panel5: TPanel;
- RichEdit1: TRichEdit;
- MainMenu1: TMainMenu;
- File1: TMenuItem;
- SaveAs1: TMenuItem;
- Save1: TMenuItem;
- Open1: TMenuItem;
- N1: TMenuItem;
- Exit1: TMenuItem;
- Edit1: TMenuItem;
- Options1: TMenuItem;
- Help1: TMenuItem;
- copy1: TMenuItem;
- N2: TMenuItem;
- Selectall1: TMenuItem;
- TextOnly1: TMenuItem;
- DefaultsOnly1: TMenuItem;
- HelpTopics1: TMenuItem;
- N3: TMenuItem;
- AboutRegenumerator1: TMenuItem;
- Panel4: TPanel;
- btnEnum: TButton;
- sbStop: TSpeedButton;
- StatusBar1: TStatusBar;
- FormStorage1: TFormStorage;
- Fullkeypaths1: TMenuItem;
- N4: TMenuItem;
- Other1: TMenuItem;
- N5: TMenuItem;
- OpenRegedit1: TMenuItem;
- SaveDialog1: TSaveDialog;
- OpenDialog1: TOpenDialog;
- Paste1: TMenuItem;
- EditPopUp: TPopupMenu;
- Bold1: TMenuItem;
- Tools1: TMenuItem;
- BackupRegistry1: TMenuItem;
- Panel6: TPanel;
- cbxMaxDepth: TLblComboBox;
- el_cbxMaxDepth: TEnhLabel;
- Panel7: TPanel;
- cbxKey: TLblComboBox;
- el_cbxKey: TEnhLabel;
- N6: TMenuItem;
- Find1: TMenuItem;
- FindNext1: TMenuItem;
- Copy2: TMenuItem;
- procedure btnEnumClick(Sender: TObject);
- procedure FormResize(Sender: TObject);
- procedure TextOnly1Click(Sender: TObject);
- procedure DefaultsOnly1Click(Sender: TObject);
- procedure AboutRegenumerator1Click(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- procedure sbStopClick(Sender: TObject);
- procedure FormClose(Sender: TObject; var Action: TCloseAction);
- procedure Fullkeypaths1Click(Sender: TObject);
- procedure Selectall1Click(Sender: TObject);
- procedure copy1Click(Sender: TObject);
- procedure Other1Click(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure OpenRegedit1Click(Sender: TObject);
- procedure Open1Click(Sender: TObject);
- procedure SaveAs1Click(Sender: TObject);
- procedure Save1Click(Sender: TObject);
- procedure Edit1Click(Sender: TObject);
- procedure Paste1Click(Sender: TObject);
- procedure Bold1Click(Sender: TObject);
- procedure BackupRegistry1Click(Sender: TObject);
- procedure HelpTopics1Click(Sender: TObject);
- procedure cbxMaxDepthChange(Sender: TObject);
- procedure Stop1Click(Sender: TObject);
- procedure FormKeyDown(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- procedure Find1Click(Sender: TObject);
- procedure FindNext1Click(Sender: TObject);
- procedure Exit1Click(Sender: TObject);
- procedure Copy2Click(Sender: TObject);
- procedure EditPopUpPopup(Sender: TObject);
- private
-
- addToResults : boolean;
- indentVal : integer;
- maxDepth : string;
-
- filename : string;
- firstsave : boolean;
-
- searchWord : string;
-
- procedure setBold;
-
- public
-
-
- //although the following funcitons are methods this is only to aid the status bar update
- //the code that would need removing can be skipped by removing the ASMETHOD define
- //Which also explainsthe presence of a couple of global variables;
- procedure regEnumerate(keyStr : string;DefaultsOnly, TextOnly, fullpath : boolean;
- indent,maxDepth : integer;sl : TStrings);
- procedure regprocesskey(key : string; DefaultsOnly, TextOnly, fullpath : boolean;
- indent,maxDepth : integer; reg : TRegistry;sl : TStrings);
- procedure findWord;
-
- end;
-
- var
- Form1: TForm1;
-
- //general stuff
- function extractRootKey(str : string):HKEY;
- function getKeyName(key : string):string;
- function regIntToStr(const i : integer):string;
- function iifStr(cond : boolean;t,f : string):string;
- function trimchar(const s : string; const c :char):string;
- function getDesktopFolder:string;
- function createIndent(size, multiplier : integer):string;
- procedure checkforstop;
-
- implementation
-
- {$R *.DFM}
-
- {$DEFINE ASMETHOD}
-
- uses strutils,about,okcancl2,inifiles,filectrl;
-
- //following is global to aid extraction of methods from class
- const stop : boolean=false;
-
- procedure TForm1.btnEnumClick(Sender: TObject);
- var
- strlist : TStringlist;
- cntr : integer;
- maxDepthVal,num : integer;
- begin
- stop:=false;
-
- //validate max depth
- try
- if cbxMaxDepth.text<>'(no limit)' then
- num:=strtoint(cbxMaxDepth.text);
- if num<0 then
- abort;
- except
- raise exception.create('Max depth must be 0, positive number or (no limit)');
- end;
-
- maxDepth:=cbxMaxDepth.text;
-
- //update combo list
- with cbxKey do begin
- if text<>'' then
- if items.indexof(text)=-1 then
- items.insert(0,text);
- while items.count>8 do
- items.delete(items.count-1);
- end;
-
-
- strlist:=TStringlist.create;
- if not addtoresults then
- richedit1.lines.clear;
-
- //disable controls
- cbxKey.enabled:=false;
- btnEnum.enabled:=false;
- file1.enabled:=false;
- edit1.enabled:=false;
- options1.enabled:=false;
- help1.enabled:=false;
- sbStop.enabled:=true;
- cbxMaxDepth.enabled:=false;
- tools1.enabled:=false;
-
- //work out max recursive depth
- if maxDepth='(no limit)' then
- maxDepthVal:=high(integer)
- else
- maxDepthVal:=strtoint(maxdepth);
- try
-
- regEnumerate(trimchar(trim(cbxKey.text),'\'),
- DefaultsOnly1.checked,TextOnly1.checked,Fullkeypaths1.checked,indentVal,maxDepthVal,strlist);
-
- statusbar1.panels.items[0].text:='Updating display (please wait)';
- try
- try
- richedit1.lines.beginupdate;
- for cntr:=0 to strlist.count-1 do begin
- checkforstop;
- //assign would have been easier? The stop button doesn't work and it takes ages.
- richedit1.lines.add(strlist[cntr]);
- end;
- finally
- richedit1.lines.endupdate;
- end;
- except
- richedit1.lines.clear;
- end;
-
- finally
- statusbar1.panels.items[0].text:='Processing key :';
- strlist.free;
- cbxKey.enabled:=true;
- btnEnum.enabled:=true;
- sbStop.enabled:=false;
- file1.enabled:=true;
- edit1.enabled:=true;
- options1.enabled:=true;
- help1.enabled:=true;
- cbxMaxDepth.enabled:=true;
- tools1.enabled:=true;
- richedit1.selstart:=0;
- end;
- end;
-
-
- //well, we're not multi-threading, are we now?
- const recurseCount : integer=0;
-
- procedure TForm1.regEnumerate(keyStr : string; DefaultsOnly, TextOnly,
- fullpath : boolean; indent,maxDepth : integer;sl : TStrings);
- var
- reg : TRegistry;
- subKeyStr : string;
- begin
- reg:=TRegistry.create;
- try
- sl.add('Enumeration of : '+cbxKey.text);
- sl.add('Options : '+
- iifStr(defaultsonly,'[Defaults only] ','')+
- iifStr(TextOnly,'[Strings only] ','')+
- iifStr(fullpath,'[Full Key Paths]',''));
- sl.add('Values denoted by "@"');
- reg.rootkey:=extractrootkey(keystr);
- if pos('\',keystr)=0 then
- subkeystr:=''
- else begin
- sl.add('');
- subKeyStr:=copy(keyStr,pos('\',keystr),length(keystr)-pos('\',keystr)+1);
- end;
- //next function is recursive
- regProcessKey(trimchar(subkeyStr,'\'),DefaultsOnly,TextOnly,fullpath,indent,maxDepth,reg,sl);
- finally
- reg.closekey;
- reg.free;
- end;
- end;
-
- //recursive;
- procedure TForm1.regprocesskey(key : string; DefaultsOnly, TextOnly, fullpath : boolean;
- indent,maxDepth : integer;reg : TRegistry;sl : TStrings);
- var subkeystrlist,valuelist : TStringlist;
- valuetype : TRegDataType;
- indentStr : string;
- cntr : integer;
- begin
-
- if recurseCount>maxdepth then
- exit;
-
- inc(recurseCount);
-
- subkeystrlist:=TStringlist.create;
- valuelist:=TStringlist.create;
- try
-
- checkforstop;
- if not reg.openkey(key,false) then
- raise exception.create('Error reading key');
-
- {$ifdef asmethod}
- statusbar1.panels.items[0].text:='Processing key : '+key;
- statusbar1.update;
- // richedit1.defattributes.style:=richedit1.defattributes.style+[fsbold];
- {$endif}
-
- indentStr:=createIndent(indent,recursecount);
- sl.add('');
- if fullpath then
- sl.add(indentstr+key)
- else
- sl.add(indentstr+getkeyname(key));
-
- {$ifdef asmethod}
- // richedit1.defattributes.style:=richedit1.defattributes.style-[fsbold];
- {$endif}
-
- reg.getvaluenames(valuelist);
- valuelist.sort;
-
- indentStr:=createIndent(indent,recursecount+1);
- for cntr:=0 to valuelist.count-1 do begin
- checkforstop;
- if (cntr=0) and defaultsonly then begin
- if valuelist[cntr]<>'' then begin
- sl.add(indentstr+'@ : [value not set]');
- break;
- end;
- end;
-
- valuetype:=reg.getdatatype(valuelist[cntr]);
- if (valuetype=rdString) or (valuetype=rdExpandString) then
- sl.add(indentStr+'@'+valuelist[cntr]+' : '+reg.readstring(valuelist[cntr]))
- else if not textonly then begin
- case valuetype of
- rdUnknown : sl.add(indentStr+'@'+valuelist[cntr]+' : [unkown]');
- rdInteger : sl.add(indentStr+'@'+valuelist[cntr]+' : [integer] hex : '+
- regIntToStr(reg.readinteger(valuelist[cntr]))+
- ' dec : '+inttostr(reg.readinteger(valuelist[cntr])));
- rdBinary : sl.add(indentStr+'@'+valuelist[cntr]+' : [binary]');
- end;
- end;
- if (cntr=0) and defaultsonly then
- break;
- end;
-
-
- reg.getkeynames(subkeystrlist);
- reg.closekey;
- subkeystrlist.sort;
- for cntr:=0 to subkeystrlist.count-1 do
- regprocesskey(key+'\'+subkeystrlist[cntr],defaultsonly,textonly,fullpath,indent,maxdepth,reg,sl);
-
-
- finally
- dec(recurseCount);
- subkeystrlist.free;
- valuelist.free;
- reg.closekey;
- end;
- end;
-
-
-
- function extractRootKey(str : string):HKEY;
- begin
- str:=ExtractWord(1,Str,['\']);
- if uppercase(str)='HKEY_CLASSES_ROOT' then
- result:=HKEY_CLASSES_ROOT
- else if uppercase(str)='HKEY_CURRENT_USER' then
- result:=HKEY_CURRENT_USER
- else if uppercase(str)='HKEY_LOCAL_MACHINE' then
- result:=HKEY_LOCAL_MACHINE
- else if uppercase(str)='HKEY_USERS' then
- result:=HKEY_USERS
- else if uppercase(str)='HKEY_CURRENT_CONFIG' then
- result:=HKEY_CURRENT_CONFIG
- else if uppercase(str)='HKEY_DYN_DATA' then
- result:=HKEY_DYN_DATA
- else begin
- raise exception.create('Root key not recognised');
- end;
- end;
-
- procedure TForm1.FormResize(Sender: TObject);
- begin
- cbxKey.width:=cbxKey.parent.width-10-cbxKey.left;
- end;
-
- procedure TForm1.TextOnly1Click(Sender: TObject);
- begin
- with textonly1 do
- checked:=not checked;
-
- end;
-
- procedure TForm1.DefaultsOnly1Click(Sender: TObject);
- begin
- with defaultsonly1 do
- checked:=not checked;
-
- end;
-
- procedure TForm1.AboutRegenumerator1Click(Sender: TObject);
- begin
- with Taboutbox.create(nil) do begin
- try
- showmodal
- finally
- free;
- end;
- end;
- end;
-
- procedure TForm1.FormCreate(Sender: TObject);
- begin
- firstsave:=true;
- stop:=false;
- application.showhint:=true;
- with Tinifile.create('regenum.ini') do begin
- try
- indentval:=readinteger('Opts','Indent',5);
- addtoresults:=readbool('Opts','addtoresults',false);
- self.filename:=readstring('General','Filename','');
- bold1.checked:=readbool('General','Bold',true);
- maxDepth:=readstring('Opts','MaxDepth','1');
- finally
- free;
- end;
- end;
- setbold;
- end;
-
- procedure TForm1.sbStopClick(Sender: TObject);
- begin
- stop:=true;
- end;
-
- procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
- begin
- stop:=true;
- end;
-
- procedure TForm1.Fullkeypaths1Click(Sender: TObject);
- begin
- with Fullkeypaths1 do
- checked:=not checked;
-
- end;
-
- function getKeyName(key : string):string;
- var
- lastSlashPos : integer;
- cntr : integer;
- begin
- if pos('\',key)=0 then
- result:=key
- else begin
- for cntr:=length(key) downto 1 do begin
- lastSlashPos:=cntr;
- if key[cntr]='\' then
- break;
- end;
- result:=copy(key,lastSlashpos+1,length(key)-lastslashpos);
- end;
- end;
-
- function createIndent(size, multiplier : integer):string;
- var
- s : string;
- len,cntr : integer;
- begin;
- len :=size*multiplier;
- setlength(s,len);
- for cntr:=1 to len do
- s[cntr]:=' ';
- result:=s;
- end;
-
- function regIntToStr(const i : integer):string;
- var
- str,str1,str2 : string;
- spos,cntr : integer;
- x : integer;
- begin
-
- // x:=356;
- str:=format('%x',[i]);
- str1:='00000000';
- spos:=8-length(str);
- for cntr:=1 to length(str) do
- str1[cntr+spos]:=str[cntr];
- str2:='';
- for cntr:=1 to length(str1) do begin
- str2:=str2+str1[cntr];
- if (cntr mod 2)=0 then
- str2:=str2+' ';
- end;
- result:=str2;
- end;
-
- function iifStr(cond : boolean;t,f : string):string;
- begin
- if cond then
- result:=t
- else
- result:=f;
- end;
-
- function trimchar(const s : string; const c :char):string;
- var
- I, L: Integer;
- begin
- L := Length(S);
- I := 1;
- while (I <= L) and (S[I] = c) do Inc(I);
- if I > L then Result := '' else
- begin
- while S[L] = c do system.Dec(L);
- Result := Copy(S, I, L - I + 1);
- end;
- end;
-
-
- procedure TForm1.Selectall1Click(Sender: TObject);
- begin
- richedit1.selectall;
- end;
-
- procedure TForm1.copy1Click(Sender: TObject);
- begin
- richedit1.copytoclipboard;
- end;
-
- procedure TForm1.Other1Click(Sender: TObject);
- begin
- with TOKRightDlg.create(nil) do begin
- try
- cbAddToResults.checked:=addtoresults;
- edIndent.text:=inttostr(indentVal);
- // cbxMaxDepth.text:=maxDepth;
- if showmodal=mrOk then begin
- addtoresults:=cbAddToResults.checked;
- indentVal:=strtoint(edIndent.text);
- // maxDepth:=cbxMaxDepth.text;
- end;
- finally
- free;
- end;
- end;
-
- end;
-
- procedure TForm1.FormDestroy(Sender: TObject);
- begin
- with Tinifile.create('regenum.ini') do begin
- try
- writeinteger('Opts','Indent',indentval);
- writebool('Opts','addtoresults',addtoresults);
- writestring('General','Filename',self.filename);
- writestring('Opts','MaxDepth',maxDepth);
- writebool('General','Bold',bold1.checked);
- finally
- free;
- end;
- end;
-
- end;
-
- procedure TForm1.OpenRegedit1Click(Sender: TObject);
- begin
- winexec('regedit.exe',sw_SHOW);
- end;
-
- procedure TForm1.Open1Click(Sender: TObject);
- var
- folder : string;
- begin
- if filename='' then
- folder:=getdesktopfolder
- else
- folder:=extractfilepath(filename);
- with opendialog1 do begin
- initialdir:=folder;
- filename:=self.filename;
- if execute then begin
- richedit1.lines.loadfromfile(filename);
- self.filename:=filename;
- caption:='REgistry enumerator : '+extractfilename(filename);
- end;
- end;
- end;
-
- procedure TForm1.SaveAs1Click(Sender: TObject);
- var
- folder : string;
- begin
- if filename='' then
- folder:=getdesktopfolder
- else
- folder:=extractfilepath(filename);
-
- with savedialog1 do begin
- initialdir:=folder;
- filename:=self.filename;
- if execute then begin
- richedit1.lines.savetofile(filename);
- firstsave:=false;
- caption:='Registry enumerator : '+extractfilename(filename);
- self.filename:=filename;
- end;
- end;
- end;
-
-
- function getDesktopFolder:string;
- begin
- with TRegistry.create do begin
- try
- try
- rootkey:=HKEY_USERS;
- if openkey('.Default\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders',false) then
- result:=readstring('Desktop')
- else
- result:='C:';
- finally
- closekey;
- free;
- end;
- except
- result:='C:';
- end;
- end
- end;
-
-
- procedure TForm1.Save1Click(Sender: TObject);
- begin
- if firstsave or (filename='') then
- saveas1click(self)
- else begin
- richedit1.lines.savetofile(filename);
- firstsave:=false;
- end;
-
- end;
-
- procedure checkforstop;
- begin
- application.processmessages;
- if stop then begin
- stop:=false;
- abort;
- end;
- end;
-
-
-
- procedure TForm1.Edit1Click(Sender: TObject);
- begin
- paste1.enabled:=activecontrol=cbxKey;
- end;
-
- procedure TForm1.Paste1Click(Sender: TObject);
- begin
- // cbxKey.pastefromclipboard;
- end;
-
- procedure TForm1.Bold1Click(Sender: TObject);
- begin
- with bold1 do checked:=not checked;
- setBold;
- end;
- procedure TForm1.BackupRegistry1Click(Sender: TObject);
- var
- //certain functions are unreliable with typecast long strings, hence a pchar :
- pwindir : pchar;
- windir : string;
- mess : string;
- ret1,ret2 : bool;
- source,dest : string;
- begin
- //it would have been nice to have used TFileOperation component (from DSP) but
- //error checking was inadequate.
- getmem(pwindir,MAX_PATH+1);
- try
- getwindowsdirectory(pwindir,MAX_PATH);
- winDir:=strpas(pwindir);
- {$i+}
- if not directoryexists(windir+'\regbackup') then
- mkdir(windir+'\regbackup');
-
- filesetattr(windir+'\regbackup\user.dat',0);
- filesetattr(windir+'\regbackup\system.dat',0);
-
- source:=windir+'\system.dat';
- dest:=windir+'\regbackup\system.dat';
- ret1:=copyfile(pchar(source),pchar(dest),false);
-
- source:=windir+'\user.dat';
- dest:=windir+'\regbackup\user.dat';
- ret2:=copyfile(pchar(source),pchar(dest),false);
-
- //copy across restore instructions
- source:=extractfilepath(paramstr(0))+'\restore.txt';
- dest:=windir+'\regbackup\restore.txt';
- copyfile(pchar(source),pchar(dest),false);
-
- filesetattr(windir+'\regbackup\user.dat',0);
- filesetattr(windir+'\regbackup\system.dat',0);
-
- if (ret1=false) or (ret2=false) then
- raise exception.create('Could not backup registry')
- else begin
- mess:='Registry saved to : '+windir+'\regbackup';
- application.messagebox(pchar(mess),'Registry Backup',mb_OK);
- end;
- finally
- freemem(pwindir,MAX_PATH+1);
- end;
-
- end;
-
- procedure TForm1.HelpTopics1Click(Sender: TObject);
- begin
- application.helpcontext(10);
- end;
-
- procedure TForm1.cbxMaxDepthChange(Sender: TObject);
- begin
- maxDepth:=cbxmaxdepth.text;
- end;
-
- procedure TForm1.Stop1Click(Sender: TObject);
- begin
- stop:=true;
- end;
-
- procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- begin
-
- if (ssAlt in shift) and ((key=byte('s')) or (key=byte('S'))) then
- stop:=true;
- end;
-
- procedure TForm1.Find1Click(Sender: TObject);
- begin
- if inputquery('Find','Text to find',SearchWord) and (searchword<>'') then
- findWord;
- end;
-
- procedure Tform1.findWord;
- var
- beforeSearchPos,SearchPos : integer;
- begin
-
- if searchWord='' then begin
- find1click(self);
- exit;
- end;
- with richedit1 do begin
- selstart:=selstart+sellength;
- beforeSearchPos:=selstart+sellength;
- SearchPos:=findtext(searchword,selstart,length(text)-selstart,[]);
- sendMessage(handle,EM_SETSEL,searchPos,SearchPos+length(searchword));
- Refresh;
- setfocus;
-
- if beforeSearchPos=(selstart+sellength) then
- raise exception.create('Not found');
- end;
-
- end;
-
-
- procedure TForm1.FindNext1Click(Sender: TObject);
- begin
- findword;
- end;
-
- procedure TForm1.Exit1Click(Sender: TObject);
- begin
- stop:=true;
- close;
- end;
-
- procedure TForm1.Copy2Click(Sender: TObject);
- begin
- richedit1.copytoclipboard;
- end;
-
- procedure TForm1.EditPopUpPopup(Sender: TObject);
- begin
- copy2.enabled:=richedit1.sellength>0;
- end;
-
- procedure TForm1.setBold;
- begin
- with bold1 do begin
- if checked then
- richedit1.font.style:=[fsbold]+richedit1.font.style
- else
- richedit1.font.style:=richedit1.font.style-[fsbold];
- end;
- end;
-
- end.
-